package cn.edu.fjnu.camera;


import android.content.Context;
import android.graphics.Matrix;
import android.util.AttributeSet;
import android.view.View;
import android.view.animation.Transformation;
import android.widget.Gallery;

public class ScaleGallery extends Gallery {

	private float mUnselectedAlpha;

	private boolean mSelectedChild;
 
	private static double SQRT_2 = Math.sqrt(2);

	public ScaleGallery(Context context) {
		super(context);
	}

	public ScaleGallery(Context context, AttributeSet attrs) {
		super(context, attrs);
		// TODO Auto-generated constructor stub
	}

	@Override
	public void setUnselectedAlpha(float unselectedAlpha) {
		mUnselectedAlpha = unselectedAlpha;
	}

	@Override
	protected void onLayout(boolean changed, int l, int t, int r, int b) {
		super.onLayout(changed, l, t, r, b);

	}

	@Override
	protected boolean getChildStaticTransformation(View child, Transformation t) {
		t.clear();
		int position = (Integer) child.getTag(); // 得到一个表位置的标签,需要在添加View时写入
		if (position == getSelectedItemPosition()) { // 得到当前选中的位置
			mSelectedChild = true; // 表示当前画的child即为选中View
		} else {
			mSelectedChild = false;
			int offset = position - getSelectedItemPosition(); // 计算当前画的child与选中View相差了几个位置
			// 用于计算不同间距的view的不同缩放`
			float scale = getScale(offset); // 根据不同位置的offset计算出缩放比例
			mUnselectedAlpha = getAlpha(offset); // 同上按照位置的offset计算出不同的透明比例
			Matrix mm = t.getMatrix(); // 由Transformation得来的3*3矩阵用于缩放
			mm.postScale(scale, scale); // 对此矩阵设置缩放
			if (offset > 0) { // 如果无以下对每个View做偏移会导致缩放后的View位置不居中
				float preScale = getScale(offset - 1);
				mm.postTranslate(child.getWidth() * (preScale - scale) / 2 - 10
						* offset, child.getHeight() * (1 - scale) / 2);
			} else {
				float preScale = getScale(offset + 1);
				mm.postTranslate(child.getWidth() * (2 - preScale - scale) / 2
						- 10 * offset, child.getHeight() * (1 - scale) / 2);
			}
		}
		t.setAlpha(mSelectedChild ? 1.0f : mUnselectedAlpha); // 设置透明度
		return true;
	}

	public float getScale(int offset) {
		/* Formula: 1 / (2 ^ offset) */
		return Math.max(0, 1.0f / (float) Math.pow(SQRT_2, Math.abs(offset)));
	}

	public float getAlpha(int offset) {
		/* Formula: 1 / (2 ^ offset) */
		return Math.max(0, 1.0f / (float) Math.pow(SQRT_2, Math.abs(offset)));
	}

}
